<?php
namespace app\data_magic\logic;

use think\Db;
use app\data_magic\extension\Filter;
use app\data_magic\extension\StringParams;


/**
 * Action的逻辑
 * @property Scene $scene 当前场景对象
 * @property array $action 当前操作的数据
 * @property array $bind_action 绑定的操作的数据
 * @property array $link_actions 关联的操作的列表
 * @property array $filters 关联的过滤器的列表     
 * 
 * @property array $input 输入的数据,进行插入和修改操作时需要
 * @property array $item 单条数据
 * @property array $list 多条数据
 */
class Action extends Scene
{
    public $bind_action=[];
    public $link_actions=[];
    public $filters=[];
    public function getDefinition()
    {
        $defi=$this->scene->getDefinition();
        $defi["link_actions"]=$this->link_actions;
        $defi["filters"]=$this->filters;
        $defi["link_action_types"]=$this->classifyLinkAction();
        return $defi;
    }
    /**
     * 加载操作
     * @param int $id 操作的id
     * @return Action
     */
    public function init($id)
    {
        if(!$id){
            $this->error="操作ID不能为空";
            return false;
        }

        $action=Db::table("dm_action")->where(["id"=>$id])->find();
        if(!$action){
            $this->error="未定义的操作";
            return false;
        }

        //读取绑定操作
        if($action["bind_action"]){
            $this->bind_action=Db::table("dm_action")->where("id = ".$action["bind_action"])->find();
        }

        //读取关联操作
        if($action["link_action"]){
            $this->link_actions=Db::table("dm_action")->where("id in (".$action["link_action"].")")->select();
        }

        //读取当前操作关联的场景
        $scene=new Scene();
        $meta=$scene->init($action["scene_id"]);
        if(!$meta){
            $this->error($scene->getError());
        }
        
        //绑定搜索条件
        if($action["bind_filter"]){
            $this->filters=$scene->getFilterList("id in (".$action["bind_filter"].")");
        }

        $this->action=$action;
        $this->scene=$scene;
        return $this;
    }
    /**
     * 将关联操作根据data_type分类
     */
    public function classifyLinkAction()
    {
        $link_action_types=["nope"=>[],"single"=>[],"multi"=>[],"where"=>[]];
        foreach($this->link_actions as $link){
            if(isset($link_action_types[$link["data_type"]])){
                $link_action_types[$link["data_type"]][]=$link;
            }
        }
        return $link_action_types;
    }

    public $user_id="0";
    public function access($user_id,$roles=[]){
        return true;
    }

    protected $query;
    public function getQuery()
    {
        if(!$this->query){
           $this->query=$this->scene->getQuery();
        }
        return $this->query;
    }
    public function dataTypeSingle($pk)
    {
        $this->getQuery()->where($this->scene->primary_key."=".$pk);
    }
    public function dataTypeMulti($pks)
    {
        $this->getQuery()->where($this->scene->primary_key." in (".$pks.")");
    }
    public function dataTypeWhere($data)
    {
        $table_id=$this->scene->structureId;
        //按照设定的搜索条件搜索
        $filters=$this->scene->getFilterList(["table_id"=>$table_id]);
        $where_array=[];
        foreach($filters as $item){
            if(!isset($data[$item["name"]]) || $data[$item["name"]]==="" ){
                continue;
            }
            
            $fields_id_list=explode(",",$item["fields"]);
            $fields_name_list=[];
            foreach($this->scene->fields as $field){
                if(in_array($field["id"],$fields_id_list)){
                    $fields_name_list[]=$field["name"];
                }
            }
            if(method_exists("Filter",$item["type"])){
                $sub_where=call_user_func(["Filter",$item["type"]],$fields_name_list,$data[$item["name"]]);
                if($sub_where){
                    $where_array[]=$sub_where;
                }
            }
            unset($data[$item["name"]]);
        }
        if($where_array){
            $where="(".implode(" ) AND ( ",$where_array).")";
            $this->getQuery()->where($where);
        }
        //不符合设定的搜索条件的参数，搜索指定的字段
        foreach($this->scene->fields as $field){
            if(!isset($data[$field["name"]]) || $data[$field["name"]]==="" ){
                continue;
            }
            $this->getQuery()->where([$field["name"]=>$data[$field["name"]]]);
        }

        //如果页面需要显示搜索，则将用户已经输入的值重新绑定到页面上
        if($this->filters){
            foreach($this->filters as $index=>$item){
                if(isset($data[$item["name"]])){
                    $this->filters[$index]["value"]=$data[$item["name"]];
                }
            }
        }
    }
    /**
     * 数据插入预处理
     * 过滤掉不允许编辑的字段
     * 将数据转换成数据库中实际保存的格式
     * 将输入的参数与预设的参数合并
     */
    public function prepData($data)
    {
        $writable=[];
        foreach($this->scene->fields as $field){
            if($field["writable"]){
                $writable[]=$field["name"];
            }
        }
        $result=[];
        foreach($data as $key => $value){
            if(in_array($key,$writable)){
                $result[$key]=$value;
            }
        }

        $field_logic=new Field();
        $result=$field_logic->convertToSaveFormat($this->scene->fields,$result);

        if($this->action["params"]){
            $param_list=explode(";",$this->action["params"]);
            foreach($param_list as $param){
                $param_part=explode(":",$param);
                if(count($param_part)===2){
                    list($key,$value)=$param_part;
                    $result[$key]=$value;
                }
            }
        }
        return $result;
    }
    public function getActionParams()
    {
        $fields=[];
        if($this->action["params"]){
            $fields=StringParams::fields($this->action["params"]);
        }
        return $fields;
    }
    public $input=[];
    public $item=[];
    public $list=[];
    // public function insert()
    // {
    //     $data=$this->prepData($this->input);
    //     $current_time=time();
    //     if($this->scene->user_id_field){
    //         $data[$this->scene->user_id_field] = $this->user_id;
    //     }
    //     if($this->scene->create_time){
    //         $data[$this->scene->create_time]=$current_time;
    //     }
    //     if($this->scene->update_time){
    //         $data[$this->scene->update_time]=$current_time;
    //     }
    //     return $this->getQuery()->insert($data);
    // }
    // public function delete()
    // {
    //     return $this->getQuery()->delete();
    // }
    // public function update()
    // {
    //     $data=$this->prepData($this->input);
    //     if($this->scene->update_time){
    //         $data[$this->scene->update_time]=time();
    //     }
    //     return $this->getQuery()->update($data);
    // }
    public function paginate($listRows = null, $simple = false, $config = [])
    {
        $this->list=$this->getQuery()->paginate($listRows, $simple, $config);
        return $this->list;
    }
    // public function select($data = null)
    // {
    //     $this->list=$this->getQuery()->select($data);
    //     return $this->list;
    // }
    // public function find($data = null)
    // {
    //     $this->item=$this->getQuery()->find($data);
    //     return $this->item;
    // }
}
